import { adapters } from "./aggregator/index";
import { getOptimismFee } from "./aggregator/utils/optimismFees";
import store from "@/store";
export const REFETCH_INTERVAL = 25000;
export const adaptersNames = adapters.map(({ name }) => name);
const adaptersMap = adapters.reduce((acc, adapter) => ({ ...acc, [adapter.name]: adapter }), {});

export async function getAdapterRoutes({ adapter, chain, from, to, amount, extra = {} }) {
  if (
    !chain ||
    !from ||
    !to ||
    (!amount && !extra.amountOut) ||
    (amount === "0" && extra.amountOut === "0")
  ) {
    return {
      price: null,
      name: adapter.name,
      airdrop: !adapter.token,
      fromAmount: amount,
      txData: "",
      l1Gas: 0,
      tx: {},
      isOutputAvailable: false,
    };
  }

  const { state } = store;
  try {
    const isOutputDefined = extra.amountOut && extra.amountOut !== "0";
    let price;
    let amountIn = amount;
    const quouteFunc = adapter.getQuote;
    if (adapter.isOutputAvailable) {
      price = await quouteFunc(chain, from, to, amount, extra);
      amountIn = price.amountIn;
    } else if (isOutputDefined && !adapter.isOutputAvailable) {
      return {
        price: null,
        name: adapter.name,
        airdrop: !adapter.token,
        fromAmount: amount,
        txData: "",
        l1Gas: 0,
        tx: {},
        isOutputAvailable: false,
      };
    } else {
      price = await quouteFunc(chain, from, to, amount, extra);
    }

    if (!amountIn) throw Error("amountIn is not defined");

    const txData = adapter?.getTxData?.(price) ?? "";
    let l1Gas = 0;

    if (chain === "optimism") {
      l1Gas = await getOptimismFee(txData);
    }

    const res = {
      price,
      l1Gas,
      gasPrice: state.gasPrice,
      txData,
      tx: adapter?.getTx?.(price),
      name: adapter.name,
      airdrop: !adapter.token,
      fromAmount: amountIn,
      isOutputAvailable: adapter.isOutputAvailable,
    };

    return res;
  } catch (e) {
    console.log(e);
    return {
      price: null,
      l1Gas: 0,
      gasPrice: state.gasPrice,
      name: adapter.name,
      airdrop: !adapter.token,
      fromAmount: amount,
      txData: "",
      tx: {},
      isOutputAvailable: false,
    };
  }
}

export async function swap({
  chain,
  from,
  to,
  amount,
  signer,
  slippage = "1",
  adapter,
  rawQuote,
  tokens,
  extra
}) {
  const aggregator = adaptersMap[adapter];

  try {
    const {
      fromToken,
      toToken,
      inAmountNum,
      outAmountNum
    } = extra;
    const res = await aggregator.swap({
      chain,
      from,
      to,
      amount,
      signer,
      slippage,
      rawQuote,
      tokens,
      extra: {
        aggregator: aggregator.name,
        inTokenSymbol: fromToken.symbol,
        inTokenAddress: fromToken.address,
        inAmountNum,
        inAmount: amount,
        outTokenSymbol: toToken.symbol,
        outTokenAddress: toToken.address,
        outAmountNum,
      }
    });
    return res;
  } catch (e) {
    throw e;
  }
}
